package org.waddy.framework.app.model.dom;

import java.io.IOException;
import java.io.InputStream;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Map;
import java.util.Properties;


import org.apache.log4j.Logger;
import org.waddy.framework.app.exception.AppException;
import org.waddy.framework.app.exception.SysException;
import org.waddy.framework.pub.util.UtilException;
import org.waddy.framework.pub.util.common.ObjectUtil;
import org.waddy.framework.sys.SysConfigDef;
import org.waddy.framework.sys.SysConfigReader;



/**
 * Title: 信息分析系统<br>
 * Description: <br>
 * Date: 2012-08-14 <br>
 * Copyright (c) 2011 PGIASoft <br>
 *
 * @author zdp
 */
public class DOMFactory {
	private static Logger log = Logger.getLogger(DOMFactory.class);

	private static DOMFactory instance;
	
	private static String DOM_MAP_FILE_NAME = "domMapFile.properties";

	private static final String DOM_IMPL_SUFFIX = "Impl";

	private static final String SEPARATOR = ".";
	
	private String runMode = SysConfigReader.getSysConfigDef().getRunMode();
	
	private static Map domImplMap = new HashMap() ;

	/**
	 * 获取DOM工厂实例，没有则创建新实例
	 * 
	 * @param path
	 * @return
	 * @throws SysException
	 * @throws AppException
	 */
	synchronized public static void initDOMFactory() throws AppException, SysException {
		if (null == instance) {
			instance = new DOMFactory();
		}
		if(!SysConfigDef.RUN_MODE_DEBUG.equals(instance.runMode)){
			//TODO 生产模式，根据打包编译生成的接口实现类映射文件，初始化delegateImplMap
			InputStream is = null;		
			is = DOMFactory.class.getClassLoader().getResourceAsStream(DOM_MAP_FILE_NAME);
			
			Properties prop = readProperties(is);
			domImplMap = getDomImpls(prop);
		}
	}

	/**
	 * 通过DAO接口类获取对应的DAO实现
	 * 
	 * @param DOMClass
	 * @return
	 * @throws AppException
	 * @throws SysException
	 */
	public static IDOM getDOM(Class DOMClass) throws AppException, SysException {
		if (null == DOMClass) {
			throw new AppException("", "无效的参数Null！");
		}
		if (null == instance) {
			initDOMFactory();
		}
		if(SysConfigDef.RUN_MODE_DEBUG.equals(instance.runMode)){
			return getDomDebugMode(DOMClass);
		}
		
		//生产模式根据实例化集合获取
		if( null == instance.domImplMap ){
			throw new AppException("10001","生产模式下未成功实例化delegate实现类！");
		}
		
		Object obj = instance.domImplMap.get(DOMClass.getName());
		if(null == obj){
			throw new AppException("10001","未找到dom（"+DOMClass.getName()+"）实现类！");
		}
		
		return (IDOM)obj;
	}
	/**
	 * 获取Debug模式下的DOM实现类 
	 * Debug模式下，直接通过dom接口类获取对应的实现
	 * 
	 * @param DelegateClass
	 * @return
	 * @throws AppException
	 * @throws SysException
	 */
	public static IDOM getDomDebugMode(Class iDomClass) throws AppException, SysException {
		
		IDOM domImpl = null;
		log.debug(iDomClass.getPackage().getName());
		log.debug(iDomClass.getName());
		
		String domImplName1 = iDomClass.getPackage().getName()+".domImpl."+iDomClass.getSimpleName();
		StringBuffer className = new StringBuffer(domImplName1);
		int i = className.lastIndexOf(SEPARATOR);

		
		className.append(DOM_IMPL_SUFFIX);
		className.deleteCharAt(i + 1);
		   	
		
		String DomImplName = className.toString();
		log.debug(className);
		try {
			domImpl = (IDOM) ObjectUtil.createByName(DomImplName);
		} catch (UtilException e) {
			log.error(DomImplName + e.getMessage());
			throw new SysException("", DomImplName + "实例化错误！",e);
		}
		return domImpl;
	}
	/**
	 * 读取配置文件配置
	 * 
	 * @param is
	 * @throws AppException
	 * @throws SysException
	 */
	private static Properties readProperties(InputStream is) throws AppException, SysException {
		if (null == is)
			throw new AppException("100005", "系统未获取到DAO接口实现类映射关系文件！");
		Properties config = new Properties();
		try {
			config.load(is);
			return config;
		} catch (IOException e) {
			throw new SysException("100005", "系统装载DAO接口实现类映射关系文件失败！",e);
		} finally {
			if (is != null) {
				try {
					is.close();
				} catch (IOException e) {
					throw new SysException("100005", "系统关闭配置读取控制错误！", e);
				}
			}
		}
	}
	/**
	 * 根据配置创建Map<delegate接口名-delegate实现对象>
	 * @param prop
	 * @return
	 * @throws AppException
	 * @throws SysException
	 */
	private static Map getDomImpls(Properties prop) throws AppException, SysException {
		Map domImpls = new HashMap();
		
		if(prop != null){
			 Enumeration emr =prop.propertyNames(); 
			 while(emr.hasMoreElements()){
				 String domInterfaceName = (String)emr.nextElement();
				 String domImplName = prop.getProperty(domInterfaceName);
				 try {
					 	Object impl = ObjectUtil.createByName(domImplName);
					 	domImpls.put(domInterfaceName, impl);
					} catch (UtilException e) {
						log.error( domImplName + "实现类反射创建错误!"+e.getMessage());
						continue;
					}
			 }
		}
		return  domImpls ;
	}
	public static void main(String[] args) throws Exception {
		//DOMFactory.getDOM(ICrmServiceDOM.class);

	}
}
